<script setup>
import { ref, computed, onMounted, watch, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import ChatView from '../../components/ChatView.vue';
import ChatComposer from '../../components/ChatComposer.vue';
import { getProductIcon } from '../../assets/theme.js';
import { useAiToolsStore } from '../../stores/aiTools';
import { useAiTimelineStore } from '../../stores/aiTimeline';
import { getAppSetting, setAppSetting } from '../../tauriApi';
import { commandService } from '../../services/commandService';

const props = defineProps({
  modelKey: { type: String, default: '' },
  keys: { type: Array, default: () => [] },
  show: { type: Boolean, default: true },
  width: { type: Number, default: 420 },
});
const emit = defineEmits(['update:modelKey', 'refresh', 'update:width']);
const { t } = useI18n();

const chatRef = ref(null);
const composerRef = ref(null);
const aiTools = useAiToolsStore();
// 新增：AI 时间线 store 与选项卡
const aiTl = useAiTimelineStore();
const activeTab = ref('chat'); // 'chat' | 'ai'
const aiItems = computed(() => aiTl.entries.slice().sort((a, b) => b.ts - a.ts));
// 新增：输入框上方折叠的时间线面板，默认折叠
const showInlineAiTimeline = ref(false);
const inlineAiItems = computed(() => aiItems.value.slice(0, 8));

// 会话 ID（独立于模型）
const sessionId = ref('default');
// 会话列表（最小实现）: { id, title, createdAt, updatedAt }
const sessions = ref([]);
let saveSessionsTimer = null;
const showSessions = ref(false);
const sessionsBtnRef = ref(null);

function formatDateId(d) {
  const pad = (n) => String(n).padStart(2, '0');
  return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
}

async function persistSessions() {
  try {
    await setAppSetting('chat.sessions', JSON.stringify(sessions.value || []));
  } catch {}
}
function schedulePersistSessions() {
  if (saveSessionsTimer) clearTimeout(saveSessionsTimer);
  saveSessionsTimer = setTimeout(persistSessions, 200);
}

async function initSessions() {
  // 恢复 active sessionId
  try {
    const savedActive = await getAppSetting('chat.session.active');
    if (savedActive && typeof savedActive === 'string') sessionId.value = savedActive;
  } catch {}

  // 恢复 sessions 列表
  try {
    const raw = await getAppSetting('chat.sessions');
    if (raw) {
      if (typeof raw === 'string') {
        try { sessions.value = JSON.parse(raw) || []; } catch { sessions.value = []; }
      } else if (Array.isArray(raw)) {
        sessions.value = raw;
      }
    }
  } catch { sessions.value = []; }

  // 如果没有会话且没有保存的活跃会话，则清空sessionId等待用户输入时创建
  if (!sessions.value.length && !sessionId.value) {
    sessionId.value = '';
  }

  // 如果有保存的sessionId但对应会话不存在，也清空
  if (sessionId.value && !sessions.value.find(s => s.id === sessionId.value)) {
    sessionId.value = '';
  }
  
  schedulePersistSessions();
}

function createNewSession() {
  const d = new Date();
  const id = `chat-${formatDateId(d)}`;
  const title = `新会话 ${d.toLocaleString()}`;
  const now = d.getTime();
  sessions.value.push({ id, title, createdAt: now, updatedAt: now });
  sessionId.value = id; // 切换到新会话
}

// 根据用户输入创建会话
function createSessionFromInput(userInput) {
  const d = new Date();
  const id = `chat-${formatDateId(d)}`;
  // 使用用户输入的前50个字符作为标题，去除换行符
  const title = userInput.replace(/\n/g, ' ').substring(0, 50).trim() || '新会话';
  const now = d.getTime();
  sessions.value.push({ id, title, createdAt: now, updatedAt: now });
  sessionId.value = id;
  schedulePersistSessions();
  return id;
}

// 新增：清空所有会话（及其聊天记录与滚动位置）
async function clearAllSessions() {
  if (!sessions.value || sessions.value.length === 0) return;
  
  // 二次确认，避免误触
  // eslint-disable-next-line no-alert
  const ok = typeof window !== 'undefined' ? window.confirm('确认清空所有会话及其聊天记录？') : true;
  if (!ok) {
    // 用户取消，关闭面板但不执行清空
    showSessions.value = false;
    return;
  }

  try {
    // 清空每个会话的持久化消息与滚动位置
    for (const s of sessions.value) {
      try { await setAppSetting(`chat.session.${s.id}`, JSON.stringify([])); } catch {}
      try { await setAppSetting(`chat.scroll.${s.id}`, '0'); } catch {}
    }

    // 清空所有会话，等待用户输入时重新创建
    sessions.value = [];
    sessionId.value = '';

    // 持久化清空后的状态
    try { await setAppSetting('chat.sessions', JSON.stringify([])); } catch {}
    try { await setAppSetting('chat.session.active', ''); } catch {}
  } finally {
    // 关闭面板
    showSessions.value = false;
  }
}

function handleSessionChange(v) {
  // 更新该会话的更新时间
  const s = sessions.value.find(s => s.id === v);
  if (s) s.updatedAt = Date.now();
}

function toggleSessionsPanel() { showSessions.value = !showSessions.value; }
function closeSessionsPanel() { showSessions.value = false; }
function onDocClick(ev) {
  try {
    const btn = sessionsBtnRef.value;
    const panel = document.getElementById('ai-sessions-panel');
    const target = ev.target;
    if (!showSessions.value) return;
    if ((btn && btn.contains(target)) || (panel && panel.contains(target))) return;
    showSessions.value = false;
  } catch {}
}
onMounted(() => { document.addEventListener('mousedown', onDocClick); });
try { onBeforeUnmount(() => { document.removeEventListener('mousedown', onDocClick); }); } catch {}

(async () => {
  await initSessions();
})();

watch(sessionId, async (v) => {
  try { await setAppSetting('chat.session.active', v || 'default'); } catch {}
  handleSessionChange(v);
  // 会话切换时刷新 AI 时间线（按工作区+会话范围）
  try { await aiTl.loadEntries(); } catch {}
});

watch(sessions, () => schedulePersistSessions(), { deep: true });

onMounted(async () => {
  // 初始加载 AI 时间线
  try { await aiTl.loadEntries(); } catch {}
});

// 发送状态直接从 ChatView 组件获取，确保状态同步
const chatSending = computed(() => {
  // 优先使用 ChatView 组件内部的 sending 状态（readonly 包装后直接访问）
  if (chatRef.value?.sending) {
    return true;
  }
  // 降级检查：如果 ChatView 不可用，则检查 aiTools 的运行任务
  return aiTools.runningTasks.some(t => t.toolId === 'chat.complete');
});

// 取消当前聊天任务的方法
function cancelCurrentChat() {
  if (chatRef.value?.cancelCurrentRequest) {
    chatRef.value.cancelCurrentRequest();
  }
}
const dragging = ref(false);
let dragStartX = 0;
let dragStartW = 0;

function onHandleDown(e) {
  if (!props.show) return;
  dragging.value = true;
  dragStartX = e.clientX;
  dragStartW = props.width;
  document.body.style.cursor = 'col-resize';
  document.body.style.userSelect = 'none';
  window.addEventListener('mousemove', onHandleMove, { passive: true });
  window.addEventListener('mouseup', onHandleUp);
}
function onHandleMove(e) {
  const dx = e.clientX - dragStartX;
  let next = dragStartW - dx;
  if (next < 0) next = 0;
  if (next > 720) next = 720;
  emit('update:width', next);
}
function onHandleUp() {
  dragging.value = false;
  document.body.style.cursor = '';
  document.body.style.userSelect = '';
  window.removeEventListener('mousemove', onHandleMove);
  window.removeEventListener('mouseup', onHandleUp);
}

// 刷新 AI 时间线
async function onRefreshClick() { try { await aiTl.loadEntries(); } catch {} }

// 处理全部拒绝 - 回退所有AI修改（占位）
async function handleRejectAll() {
  if (aiItems.value.length === 0) return;
  try {
    const result = await aiTl.rollbackAll({ log: false, clear: true });
    if (result.success) {
      await aiTl.loadEntries();
    }
  } catch (e) {
    // 错误提示
  }
}

// 新增：处理全部接受 - 清空时间线
async function handleAcceptAll() {
  if (aiItems.value.length === 0) return;
  try {
    await aiTl.clearTimeline();
    await aiTl.loadEntries();
  } catch (e) {}
}

// 处理时间线条目点击 - 显示文件diff
function handleTimelineItemClick(entry) {
  console.log('Timeline item clicked:', entry);
  // 仅基于工作区打开文件标签页，是否展示 diff 由标签页自身监听决定
  try {
    commandService.execute('file:openPath', { uri: entry.path });
  } catch (error) {
  // Fallback to legacy timeline.open if file:openPath is not registered yet
  try {
    commandService.execute('timeline.open', { uri: entry.path });
  } catch (e2) {
    console.error('Failed to open file from AI timeline (fallback failed):', e2);
  }
}
}

// 处理发送消息事件
async function handleSendMessage(text) {
  // 如果没有当前会话，根据用户输入创建新会话
  if (!sessionId.value || !sessions.value.find(s => s.id === sessionId.value)) {
    createSessionFromInput(text);
    // 等待多个tick确保ChatView组件完全处理完sessionId变化和消息加载
    await nextTick();
    await nextTick();
    // 再次确认ChatView已准备好
    setTimeout(() => {
      if (chatRef.value?.sendText) {
        chatRef.value.sendText(text);
      }
    }, 50);
  } else {
    // 发送消息到聊天组件
    if (chatRef.value?.sendText) {
      chatRef.value.sendText(text);
    }
  }
}

// 处理回退到输入框的事件
async function handleRetractToInput(messageContent, messageTimestamp) {
  // 将消息内容设置到ChatComposer的输入框中
  if (composerRef.value && composerRef.value.text !== undefined) {
    composerRef.value.text = messageContent;
  }
  
  // 集成AI时间线系统，回退从消息时间戳开始的所有文件变更
  if (messageTimestamp) {
    try {
      console.log('Rolling back AI changes from timestamp:', messageTimestamp);
      const result = await aiTl.rollbackFromTimestamp(messageTimestamp, { 
        log: false, // 不记录回退操作到时间线
        clear: true // 清空相关时间线条目
      });
      
      if (result.success) {
        console.log(`Successfully rolled back ${result.count} changes`);
        // 刷新AI时间线显示
        await aiTl.loadEntries();
      } else {
        console.warn('Some rollback operations failed:', result.errors);
      }
    } catch (error) {
      console.error('Failed to rollback AI changes:', error);
    }
  }
  
  console.log('Retracted to input with content:', messageContent);
}
</script>

<template>
  <aside
    class="relative min-w-0 overflow-hidden bg-panel-bg/60 flex h-full min-h-0 flex-col"
    :class="[show ? 'border-l border-panel-border' : 'border-l-0', dragging ? '' : 'transition-[width] duration-200 ease-in-out']"
    :style="{ width: show ? (width + 'px') : '0px' }"
  >
    <!-- Drag handle: keep visual line thin (1px) but enlarge hit area for better usability -->
    <div class="absolute left-0 top-0 h-full w-3 z-10 group">
      <!-- Visible 1px highlight line (consistent with other panels) -->
      <div class="absolute left-0 top-0 h-full w-px bg-transparent pointer-events-none group-hover:bg-purple-500/60"></div>
      <!-- Invisible enlarged hit area capturing drag events -->
      <div class="absolute inset-0 cursor-col-resize touch-none" @mousedown="onHandleDown"></div>
    </div>
    <div class="h-9 flex items-center justify-between gap-2 px-2 border-b border-panel-border text-xs font-medium">
      <div class="flex items-center gap-1 text-muted-fg">
        <span class="px-2 h-7 inline-flex items-center justify-center rounded-md bg-subtle-bg text-panel-fg">{{ t('chat.title') || 'Chat' }}</span>
      </div>
      <div class="flex items-center gap-1.5">
        <!-- 会话列表图标按钮（面板展示） -->
        <button
          ref="sessionsBtnRef"
          class="inline-flex h-7 w-7 items-center justify-center rounded-md border border-panel-border bg-panel-bg text-panel-fg hover:bg-subtle-bg"
          @click="toggleSessionsPanel"
          title="会话列表"
          aria-label="会话列表"
        >
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4">
            <path d="M8 6h13"/>
            <path d="M8 12h13"/>
            <path d="M8 18h13"/>
            <rect x="3" y="5" width="3" height="2" rx="0.5" />
            <rect x="3" y="11" width="3" height="2" rx="0.5" />
            <rect x="3" y="17" width="3" height="2" rx="0.5" />
          </svg>
        </button>
        <button
          class="inline-flex h-7 w-7 items-center justify-center rounded-md border border-panel-border bg-panel-bg text-panel-fg hover:bg-subtle-bg"
          @click="onRefreshClick"
          :title="t('app.refresh')"
          :aria-label="t('app.refresh')"
        >
          <span v-html="getProductIcon('refresh', 'h-4 w-4')"></span>
        </button>
      </div>
    </div>

    <!-- 会话面板 -->
    <div v-if="showSessions" id="ai-sessions-panel" class="absolute right-2 top-10 z-50 w-64 rounded-md border border-panel-border bg-panel-bg shadow-lg">
      <div class="flex h-8 items-center justify-between px-2 text-[12px] border-b border-panel-border">
        <span class="text-panel-fg">会话</span>
        <div class="flex items-center gap-1">
          <button class="h-6 px-2 inline-flex items-center justify-center rounded-md border border-panel-border bg-panel-bg text-panel-fg hover:bg-subtle-bg text-[12px]"
                  @click="clearAllSessions">清空</button>
          <button class="h-6 px-2 inline-flex items-center justify-center rounded-md border border-panel-border bg-panel-bg text-panel-fg hover:bg-subtle-bg text-[12px]"
                  @click="createNewSession">新建</button>
        </div>
      </div>
      <div class="max-h-64 overflow-auto thin-scrollbar scrollbar-compact">
        <div v-for="s in sessions" :key="s.id" @click="sessionId = s.id; closeSessionsPanel()"
             class="flex items-center justify-between px-2 h-8 cursor-pointer text-[12px] text-panel-fg hover:bg-subtle-bg">
          <div class="truncate mr-2" :title="s.title || s.id">{{ s.title || s.id }}</div>
          <span v-if="sessionId === s.id" class="text-[10px] text-emerald-600 dark:text-emerald-400">当前</span>
        </div>
        <div v-if="!sessions || !sessions.length" class="px-2 py-2 text-[12px] text-muted-fg">发送消息时将自动创建会话</div>
      </div>
    </div>

    <!-- 移除原有的会话选择行，改用上方工具栏图标+面板 -->

    <!-- Chat 区域 -->
    <div class="flex-1 min-h-0 overflow-hidden">
      <ChatView ref="chatRef" :modelKey="modelKey" :sessionId="sessionId" @retract-to-input="handleRetractToInput">
        <div class="p-2 space-y-2">
          <!-- 折叠的 AI 时间线（默认折叠） -->
          <div class="rounded-md border border-panel-border bg-panel-bg">
            <div class="flex items-center justify-between">
              <button type="button" class="flex-1 flex items-center justify-between px-2 h-7 text-[12px] text-panel-fg"
                @click="showInlineAiTimeline = !showInlineAiTimeline">
                <div class="flex items-center gap-2">
                  <span class="font-medium">AI 时间线</span>
                  <span class="text-[11px] text-slate-400 dark:text-neutral-500">({{ aiItems.length }})</span>
                </div>
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"
                     class="h-3.5 w-3.5 text-slate-500 dark:text-neutral-400 transition-transform"
                     :style="{ transform: showInlineAiTimeline ? 'rotate(90deg)' : 'rotate(0deg)' }">
                  <path d="m9 5 7 7-7 7" />
                </svg>
              </button>
              <div v-if="aiItems.length > 0" class="flex items-center gap-1 px-1">
                <button type="button"
                  class="px-2 py-0.5 text-[10px] rounded bg-red-600 text-white hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600"
                  @click="handleRejectAll"
                  title="全部拒绝 - 回退所有AI修改">
                  全部拒绝
                </button>
                <button type="button"
                  class="px-2 py-0.5 text-[10px] rounded bg-[#32CD79] text-white hover:bg-[#2ebd70] dark:bg-[#32CD79] dark:hover:bg-[#2ebd70]"
                  @click="handleAcceptAll"
                  title="全部接受 - 清空时间线">
                  全部接受
                </button>
              </div>
            </div>
            <div v-show="showInlineAiTimeline" class="px-1.5 py-1 border-t border-panel-border max-h-32 overflow-auto thin-scrollbar scrollbar-compact scrollbar-track">
              <div class="text-[11px] text-muted-fg mb-1">最近记录</div>
              <div class="space-y-0.5">
                <div v-for="e in inlineAiItems" :key="e.id" class="flex items-center gap-2 px-1.5 py-1 rounded hover:bg-subtle-bg cursor-pointer select-none" @click="handleTimelineItemClick(e)">
                  <div class="text-[11px] text-muted-fg min-w-[48px]">{{ new Date(e.ts).toLocaleTimeString() }}</div>
                  <div class="flex-1 min-w-0">
                    <div class="text-[12px] truncate">
                      <span class="font-medium">{{ (e.kind || '').toUpperCase() }}</span>
                      <span class="mx-1">·</span>
                      <span>{{ e.tool || 'AI' }}</span>
                    </div>
                    <div class="text-[11px] text-muted-fg truncate">{{ e.path }}</div>
                  </div>
                  <div v-if="e.replacements" class="text-[10px] text-muted-fg ml-2">×{{ e.replacements }}</div>
                </div>
              </div>
            </div>
          </div>

          <ChatComposer
            ref="composerRef"
            :keys="keys"
            :modelKey="modelKey"
            @update:modelKey="$emit('update:modelKey', $event)"
            :sending="chatSending"
            @send="handleSendMessage"
            @cancel="cancelCurrentChat"
          />
        </div>
      </ChatView>
    </div>

    <!-- 移除独立 AI 时间线页签 -->
  </aside>
</template>

<style scoped>
.thin-scrollbar::-webkit-scrollbar { width: 8px; height: 8px; }
html:not(.dark) .thin-scrollbar::-webkit-scrollbar-thumb { background-color: rgba(100,116,139,.55); border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }
html.dark .thin-scrollbar::-webkit-scrollbar-thumb { background-color: rgba(148,163,184,.45); border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }
</style>



